import { addAppShareLog, miniProgramCode } from '@/api';
import { ThridTypeEnum } from '@/enums/LoginEnum';
import { DocumentFileType } from '@/hooks/file/type';
import { useEnv } from '@/hooks/useEnv';
import { getUrl } from '@/router';
import { PagesType } from '@/router/types/pages';
import { isString } from 'lodash-es';

/**
 * 给对象添加一些自定义方法
 * @param obj Object 实例
 * @returns Object
 */
export function setObjMethod<T = object>(obj: object = {}) {
  return Object.assign(
    Object.create({
      get(key: keyof T, value: any) {
        const v = (this as any)[key];
        return v === undefined ? value : v;
      },
    }),
    obj,
  ) as T;
}

/**
 * 提示
 * @param data 提示内容
 * @param {string} icon 提示图标
 */
export function Toast(
  data?: UniApp.ShowToastOptions | string,
  icon?: 'success' | 'error' | 'none',
  duration = 1500,
  mask = true,
) {
  if (!data) return;
  data = isString(data) ? { title: data } : data;
  const success = data.success;
  if (success) {
    setTimeout(success, data?.duration || duration);
  }
  delete data.success;
  return uni.showToast({
    duration,
    icon: icon || 'none',
    mask: mask,
    ...data,
  });
}

/**
 * @description 是否是网络地址
 * @date 19/09/2023
 * @export
 * @param {string} path
 * @returns {*}  {boolean}
 */
export function isReqUrl(path: string): boolean {
  const reg = /(http|https):\/\/([\w.]+\/?)\S*/;
  return reg.test(path);
}

/**
 *延时器
 * @param ms 毫秒
 * @returns
 */
export function delay(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}


/**
 * @description svg转dataUrl
 * @date 06/05/2023
 * @export
 * @param {string} svg
 * @returns {string}
 */
export function svgToDataUrl(svg: string): string {
  if (!svg) return '';
  // 将被设置到 dataset 中的属性还原出来
  svg = svg.replace(/data-(.*?=(['"]).*?\2)/g, '$1');

  // 将被设置到 data-xlink-href 的属性还原出来
  svg = svg.replace(/xlink-href=/g, 'xlink:href=');

  // 将 dataset 中被变成 kebab-case 写法的 viewBox 还原出来
  svg = svg.replace(/view-box=/g, 'viewBox=');

  // 清除 SVG 中不应该显示的 title、desc、defs 元素
  svg = svg.replace(/<(title|desc|defs)>[\s\S]*?<\/\1>/g, '');

  // 为非标准 XML 的 SVG 添加 xmlns，防止视图层解析出错
  if (!/xmlns=/.test(svg)) svg = svg.replace(/<svg/, "<svg xmlns='http://www.w3.org/2000/svg'");

  // 对 SVG 中出现的浮点数统一取最多两位小数，缓解数据量过大问题
  svg = svg.replace(/\d+\.\d+/g, (match) => parseFloat(parseFloat(match).toFixed(2)).toString());

  // 清除注释，缓解数据量过大的问题
  svg = svg.replace(/<!--[\s\S]*?-->/g, '');

  // 模拟 HTML 的 white-space 行为，将多个空格或换行符换成一个空格，减少数据量
  svg = svg.replace(/\s+/g, ' ');

  // 对特殊符号进行转义，这里参考了 https://github.com/bhovhannes/svg-url-loader/blob/master/src/loader.js
  svg = svg.replace(/[{}\|\\\^~\[\]`"<>#%]/g, function (match) {
    return '%' + match[0].charCodeAt(0).toString(16).toUpperCase();
  });

  // 单引号替换为 \'，由于 kbone 的 bug，节点属性中的双引号在生成 outerHTML 时不会被转义导致出错
  // 因此 background-image: url( 后面只能跟单引号，所以生成的 URI 内部也就只能用斜杠转义单引号了
  svg = svg.replace(/'/g, "\\'");

  // 最后添加 mime 头部，变成 Webview 可以识别的 Data URI
  return 'data:image/svg+xml,' + svg.trim();
}

/**
 * @description 获取文件图标
 * @param {string} fileSuffix
 * @returns {Object}
 */
export const getFileIcon = (fileSuffix: DocumentFileType): { icon: string, color: string } => {
  const type = (fileSuffix[0] === '.' ? fileSuffix.slice(1) : fileSuffix) as DocumentFileType
  const obj = {
    icon: '',
    color: '',
  };

  switch (type) {
    case 'docx':
    case 'doc':
      obj.icon = 'icon-a-Property1doc';
      obj.color = '#3A80FC';
      break;
    case 'pptx':
    case 'ppt':
      obj.icon = 'icon-a-Property1PPT';
      obj.color = '#F34E19';
      break;
    case 'pdf':
      obj.icon = 'icon-a-Property1PDF';
      obj.color = '#F24949';
      break;
    default:
      obj.icon = 'icon-a-Property1doc';
      obj.color = '#3A80FC';
  }
  return obj;
};


/**
 * 更新计数器值（确保不会小于0）
 * @param currentValue 当前计数值
 * @param changeAmount 变更数量
 * @param operationType 操作类型：'add'增加，其他减少
 * @returns 更新后的计数值
 */
export function updateCounter(currentValue: number, changeAmount: number, operationType: 'add' | 'subtract'): number {
  if (operationType === 'add') {
    return currentValue + changeAmount;
  } else {
    return currentValue === 0 ? 0 : Math.max(0, currentValue - changeAmount);
  }
}

/**
 * @description 创建小程序二维码
 * @date 18/10/2022
 * @export
 * @param {{ path: PagesType; query: Recordable }} data
 */
export async function createMiniCode(data: { path: PagesType; query: Recordable }) {
  const { path, query } = data;
  try {
    // 获取小程序码
    const { envVersion } = useEnv();
    const { id } = await addAppShareLog({
      path: getUrl(path),
      query: JSON.stringify({ ...query }),
    });
    return await miniProgramCode({
      scene: id.toString(),
      page: getUrl('startPage'),
      tripartiteName: 'mini_yjr',
      thridType: ThridTypeEnum.MINIAPP,
      env_version: envVersion,
      check_path: true,
    });
  } catch (error) {
    console.error(error);
    return '';
  }
}